<?php
namespace app\api\model;

use think\Model;
use think\facade\Db;

class Chat extends Model
{
    protected $pk = 'id';
    // ThinkPHP会自动添加表前缀，所以这里只需要写表名（不含前缀）
    protected $name = 'chat_messages';
    
    // 设置自动时间戳（ThinkPHP 8使用int类型时间戳）
    protected $autoWriteTimestamp = 'int';
    protected $createTime = 'create_time';
    protected $updateTime = false; // 消息表不需要更新时间
    
    /**
     * 发送消息
     */
    public static function sendMessage($data)
    {
        $message = new self();
        // 确保所有字段都是正确的类型，避免数组转换错误
        $message->client_uuid = (string)($data['client_uuid'] ?? '');
        $message->sender_type = (int)($data['sender_type'] ?? 1); // 1-客户，2-客服
        $message->admin_id = (int)($data['admin_id'] ?? 0);
        $message->message = (string)($data['message'] ?? '');
        $message->message_type = (int)($data['message_type'] ?? 1); // 1-文本，2-图片
        $message->image_url = (string)($data['image_url'] ?? '');
        $message->goods_id = (int)($data['goods_id'] ?? 0);
        // create_time会自动设置，因为设置了autoWriteTimestamp
        $message->save();
        
        // 将模型转换为数组，避免返回模型对象时出现数组转换错误
        $messageData = $message->toArray();
        
        return ['code' => 200, 'msg' => '发送成功', 'data' => $messageData];
    }
    
    /**
     * 获取聊天记录
     */
    public static function getMessages($clientUuid, $page = 1, $pageSize = 50)
    {
        // 按ID升序排序（ID小的先插入，先显示），然后按时间戳升序作为辅助排序
        // 这样确保消息按照插入顺序显示，图片消息（先发送）会显示在文字消息（后发送）之前
        $query = self::where('client_uuid', $clientUuid)
            ->order('id', 'asc')  // 首先按ID升序，确保按插入顺序
            ->order('create_time', 'asc');  // 其次按时间戳升序，作为辅助排序
        
        // $list = $query->paginate([
        //     'list_rows' => $pageSize,
        //     'page' => $page
        // ]);
        $list = $query->select();
        // 不需要反转，因为已经是升序了
        // $messages = $list->items();
        $messages = $list;
        
        return [
            'code' => 200,
            'msg' => 'success',
            'data' => [
                'list' => $messages,
                'total' => $list->total(),
                'page' => $page,
                'pageSize' => $pageSize
            ]
        ];
    }
    
    /**
     * 获取未读消息数量
     */
    public static function getUnreadCount($clientUuid, $senderType = 1)
    {
        // senderType = 1 时，获取客服的未读消息（sender_type=2且is_read=0）
        // senderType = 2 时，获取客户的未读消息（sender_type=1且is_read=0）
        $targetSenderType = $senderType == 1 ? 2 : 1;
        
        $count = self::where('client_uuid', $clientUuid)
            ->where('sender_type', $targetSenderType)
            ->where('is_read', 0)
            ->count();
        
        // 确保返回整数类型
        return (int)$count;
    }
    
    /**
     * 标记消息为已读
     */
    public static function markAsRead($clientUuid, $senderType = 1)
    {
        // senderType = 1 时，标记客服消息为已读
        // senderType = 2 时，标记客户消息为已读
        $targetSenderType = $senderType == 1 ? 2 : 1;
        
        self::where('client_uuid', $clientUuid)
            ->where('sender_type', $targetSenderType)
            ->where('is_read', 0)
            ->update(['is_read' => 1]);
        
        return ['code' => 200, 'msg' => '标记成功'];
    }
    
    /**
     * 获取用户列表（客服端）- 包括在线和离线用户
     * 返回所有访问过聊天页面的用户（包括未发送消息的用户）
     */
    public static function getOnlineUsers($page = 1, $pageSize = 20, $timeout = 300)
    {
        // 确保参数是整数类型
        $page = (int)$page;
        $pageSize = (int)$pageSize;
        $timeout = (int)$timeout;
        
        // 获取最近N秒内有活动的用户视为在线（默认5分钟）
        $activeTime = (int)time() - $timeout;
        
        // 从在线用户表获取所有用户（包括未发送消息的用户）
        // 这样可以显示所有访问过聊天页面的用户
        $onlineUsersData = Db::name('chat_online_users')
            ->order('last_active_time', 'desc')
            ->select()
            ->toArray();
        
        if (empty($onlineUsersData)) {
            return [
                'code' => 200,
                'msg' => 'success',
                'data' => [
                    'list' => [],
                    'total' => 0,
                    'page' => $page,
                    'pageSize' => $pageSize
                ]
            ];
        }
        
        // 获取所有用户UUID
        $allClientUuids = array_column($onlineUsersData, 'client_uuid');
        
        // 批量获取每个用户的最后一条消息（提高性能）
        $lastMessages = [];
        if (!empty($allClientUuids)) {
            foreach ($allClientUuids as $clientUuid) {
                $lastMessage = self::where('client_uuid', $clientUuid)
                    ->order('create_time', 'desc')
                    ->find();
                if ($lastMessage) {
                    $lastMessages[$clientUuid] = $lastMessage->toArray();
                }
            }
        }
        
        // 构建用户列表
        $users = [];
        foreach ($onlineUsersData as $userData) {
            $clientUuid = $userData['client_uuid'];
            $lastActiveTime = isset($userData['last_active_time']) ? (int)$userData['last_active_time'] : 0;
            $isOnline = $lastActiveTime >= $activeTime;
            
            // 获取最后一条消息
            $lastMessageTime = 0;
            $lastMessageText = '';
            if (isset($lastMessages[$clientUuid])) {
                $lastMessageData = $lastMessages[$clientUuid];
                $lastMessageTime = isset($lastMessageData['create_time']) ? (int)$lastMessageData['create_time'] : 0;
                
                // 如果是图片消息，显示"[图片]"，否则显示文本内容
                if (isset($lastMessageData['message_type']) && $lastMessageData['message_type'] == 2) {
                    $lastMessageText = '[图片]';
                } else {
                    $lastMessageText = isset($lastMessageData['message']) ? (string)$lastMessageData['message'] : '';
                }
                
                // 如果在线状态表中没有活跃时间，使用最后一条消息的时间
                if ($lastActiveTime == 0 && $lastMessageTime > 0) {
                    $lastActiveTime = $lastMessageTime;
                    // 重新计算在线状态
                    $isOnline = $lastActiveTime >= $activeTime;
                }
            }
            
            // 获取未读消息数（只有发送过消息的用户才有未读消息）
            $unreadCount = 0;
            if (isset($lastMessages[$clientUuid])) {
                $unreadCount = (int)self::getUnreadCount($clientUuid, 2); // 客服端查看客户消息
            }
            
            $users[] = [
                'client_uuid' => (string)$clientUuid,
                'last_active_time' => $lastActiveTime > 0 ? (int)$lastActiveTime : 0,
                'last_message' => $lastMessageText,
                'last_message_time' => $lastMessageTime > 0 ? (int)$lastMessageTime : 0,
                'unread_count' => (int)$unreadCount,
                'is_online' => (bool)$isOnline
            ];
        }
        
        // 按最后活跃时间或最后消息时间排序（最新的在前）
        // 优先使用最后消息时间，如果没有消息则使用最后活跃时间
        usort($users, function($a, $b) {
            // 优先使用最后消息时间，如果没有消息则使用最后活跃时间
            $timeA = $a['last_message_time'] > 0 ? $a['last_message_time'] : $a['last_active_time'];
            $timeB = $b['last_message_time'] > 0 ? $b['last_message_time'] : $b['last_active_time'];
            return $timeB - $timeA;
        });
        
        // 分页处理
        $total = count($users);
        $offset = ($page - 1) * $pageSize;
        // $pagedUsers = array_slice($users, $offset, $pageSize);
        $pagedUsers = $users;
        return [
            'code' => 200,
            'msg' => 'success',
            'data' => [
                'list' => $pagedUsers,
                'total' => (int)$total,
                'page' => (int)$page,
                'pageSize' => (int)$pageSize
            ]
        ];
    }
    
    /**
     * 更新用户在线状态
     */
    public static function updateOnlineStatus($clientUuid, $ipAddress = '', $userAgent = '')
    {
        $data = [
            'client_uuid' => $clientUuid,
            'last_active_time' => time(),
            'ip_address' => $ipAddress,
            'user_agent' => $userAgent
        ];
        
        $exists = Db::name('chat_online_users')
            ->where('client_uuid', $clientUuid)
            ->find();
        
        if ($exists) {
            Db::name('chat_online_users')
                ->where('client_uuid', $clientUuid)
                ->update($data);
        } else {
            $data['create_time'] = time();
            Db::name('chat_online_users')->insert($data);
        }
    }
    
    /**
     * 获取与特定用户的聊天记录（客服端）
     */
    public static function getChatByUuid($clientUuid, $page = 1, $pageSize = 50)
    {
        return self::getMessages($clientUuid, $page, $pageSize);
    }
}

